home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DKBSRC.ARJ / TARGA.C < prev    next >
C/C++ Source or Header  |  1991-05-04  |  8KB  |  241 lines

  1. /*****************************************************************************
  2. *
  3. *                                     Targa.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module contains the code to read and write the Targa output file
  8. *  format.
  9. *
  10. * This software is freely distributable. The source and/or object code may be
  11. * copied or uploaded to communications services so long as this notice remains
  12. * at the top of each file.  If any changes are made to the program, you must
  13. * clearly indicate in the documentation and in the programs startup message
  14. * who it was who made the changes. The documentation should also describe what
  15. * those changes were. This software may not be included in whole or in
  16. * part into any commercial package without the express written consent of the
  17. * author.  It may, however, be included in other public domain or freely
  18. * distributed software so long as the proper credit for the software is given.
  19. *
  20. * This software is provided as is without any guarantees or warranty. Although
  21. * the author has attempted to find and correct any bugs in the software, he
  22. * is not responsible for any damage caused by the use of the software.  The
  23. * author is under no obligation to provide service, corrections, or upgrades
  24. * to this package.
  25. *
  26. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  27. * about them.  Also, if you have any comments or questions, you may contact me
  28. * at the following address:
  29. *
  30. *     David Buck
  31. *     22C Sonnet Cres.
  32. *     Nepean Ontario
  33. *     Canada, K2H 8W7
  34. *
  35. *  I can also be reached on the following bulleton boards:
  36. *
  37. *     OMX              (613) 731-3419
  38. *     Mystic           (613) 596-4249  or  (613) 596-4772
  39. *
  40. *  Fidonet:   1:163/109.9
  41. *  Internet:  dbuck@ccs.carleton.ca
  42. *  The "You Can Call Me RAY" BBS    (708) 358-5611
  43. *
  44. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  45. *
  46. *     The "You Can Call Me RAY" BBS (708) 358-5611
  47. *     The Information Exchange BBS  (708) 945-5575
  48. *
  49. *****************************************************************************/
  50.  
  51. #include "frame.h"
  52. #include "dkbproto.h"
  53.  
  54. extern int First_Line;
  55.  
  56. FILE_HANDLE *Get_Targa_File_Handle()
  57.    {
  58.    FILE_HANDLE *handle;
  59.  
  60.    if ((handle = (FILE_HANDLE *) malloc(sizeof(FILE_HANDLE))) == NULL) {
  61.       fprintf (stderr, "Cannot allocate memory for output file handle\n");
  62.       return(NULL);
  63.       }
  64.  
  65.    handle->Default_File_Name_p = Default_Targa_File_Name;
  66.    handle->Open_File_p = Open_Targa_File;
  67.    handle->Write_Line_p = Write_Targa_Line;
  68.    handle->Read_Line_p = Read_Targa_Line;
  69.    handle->Close_File_p = Close_Targa_File;
  70.    return (handle);
  71.    }
  72.  
  73. char *Default_Targa_File_Name()
  74.    {
  75.    return ("data.tga");
  76.    }
  77.  
  78. int Open_Targa_File (handle, name, width, height, buffer_size, mode)
  79.    FILE_HANDLE *handle;
  80.    char *name;
  81.    int *width;
  82.    int *height;
  83.    int buffer_size;
  84.    int mode;
  85.    {
  86.    int data1, data2, i;
  87.  
  88.    handle->mode = mode;
  89.    handle->filename = name;
  90.  
  91.    switch (mode) {
  92.       case READ_MODE:
  93.          if ((handle->file = fopen (name, "rb")) == NULL)
  94.             return(0);
  95.  
  96.          if (buffer_size != 0) {
  97.             if ((handle->buffer = malloc (buffer_size)) == NULL)
  98.                return(0);
  99.  
  100.             setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
  101.             }
  102.  
  103.          for (i = 0 ; i < 12 ; i++)
  104.             if (getc(handle->file) == EOF)
  105.                return(0);
  106.  
  107.          if (((data1 = getc(handle->file)) == EOF)
  108.              || ((data2 = getc(handle->file)) == EOF))
  109.             return(0);
  110.  
  111.          *width  = data2 * 256 + data1;
  112.  
  113.          if (((data1 = getc(handle->file)) == EOF)
  114.              || ((data2 = getc(handle->file)) == EOF))
  115.             return(0);
  116.  
  117.          for (i = 0 ; i < 2 ; i++)
  118.             if (getc(handle->file) == EOF)
  119.                return(0);
  120.  
  121.          *height = data2 * 256 + data1;
  122.          handle->width = *width;
  123.          handle->height = *height;
  124.          handle->buffer_size = buffer_size;
  125.          break;
  126.  
  127.       case WRITE_MODE:
  128.          if ((handle->file = fopen (name, "wb")) == NULL)
  129.             return(0);
  130.  
  131.          if (buffer_size != 0) {
  132.             if ((handle->buffer = malloc (buffer_size)) == NULL)
  133.                return(0);
  134.  
  135.             setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
  136.             }
  137.  
  138.          for (i = 0; i < 10; i++)    /* 00, 00, 02, then 7 00's... */
  139.             if (i == 2)
  140.                putc(i, handle->file);
  141.             else
  142.                putc(0, handle->file);
  143.  
  144.          putc(First_Line % 256, handle->file); /* y origin set to "First_Line" */
  145.          putc(First_Line / 256, handle->file);
  146.  
  147.          putc(*width % 256, handle->file);  /* write width and height */
  148.          putc(*width / 256, handle->file);
  149.          putc(*height % 256, handle->file);
  150.          putc(*height / 256, handle->file);
  151.          putc(24, handle->file);        /* 24 bits/pixel (16 million colors!) */
  152.          putc(32, handle->file);        /* Bitmask, pertinent bit: top-down raster */
  153.  
  154.          handle->width = *width;
  155.          handle->height = *height;
  156.          handle->buffer_size = buffer_size;
  157.  
  158.          break;
  159.  
  160.       case APPEND_MODE:
  161.          if ((handle->file = fopen (name, "ab")) == NULL)
  162.             return(0);
  163.  
  164.          if (buffer_size != 0) {
  165.             if ((handle->buffer = malloc (buffer_size)) == NULL)
  166.                return(0);
  167.  
  168.             setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
  169.             }
  170.  
  171.          break;
  172.       }
  173.    return(1);
  174.    }
  175.  
  176. void Write_Targa_Line (handle, line_data, line_number)
  177.    FILE_HANDLE *handle;
  178.    COLOUR *line_data;
  179.    int line_number;
  180.    {
  181.    register int x;
  182.  
  183.    for (x = 0; x < handle->width; x++) {
  184.       putc((int) floor (line_data[x].Blue * 255.0), handle->file);
  185.       putc((int) floor (line_data[x].Green * 255.0), handle->file);
  186.       putc((int) floor (line_data[x].Red * 255.0), handle->file);
  187.       }
  188.  
  189.    if (handle->buffer_size == 0) {
  190.       fflush(handle->file);                       /* close and reopen file for */
  191.       handle->file = freopen(handle->filename, "ab",
  192.                     handle->file);                /* integrity in case we crash*/
  193.       }
  194.    }
  195.  
  196. int Read_Targa_Line (handle, line_data, line_number)
  197.    FILE_HANDLE *handle;
  198.    COLOUR *line_data;
  199.    int *line_number;
  200.    {
  201.    int x, data;
  202. static int Targa_Line_Number = 0;
  203.  
  204.    for (x = 0; x < handle->width; x++) {
  205.  
  206.    /* Read the BLUE data byte.  If EOF is reached on the first character read,
  207.       then this line hasn't been rendered yet.  Return 0.  If an EOF occurs
  208.       somewhere within the line, this is an error - return -1. */
  209.  
  210.       if ((data = getc(handle->file)) == EOF)
  211.          if (x == 0)
  212.             return (0);
  213.          else
  214.             return (-1);
  215.  
  216.       line_data[x].Blue = (DBL) data / 255.0;
  217.  
  218.    /* Read the GREEN data byte. */
  219.       if ((data = getc(handle->file)) == EOF)
  220.          return (-1);
  221.       line_data[x].Green = (DBL) data / 255.0;
  222.  
  223.  
  224.    /* Read the RED data byte. */
  225.       if ((data = getc(handle->file)) == EOF)
  226.          return (-1);
  227.       line_data[x].Red = (DBL) data / 255.0;
  228.       }
  229.  
  230.    *line_number = Targa_Line_Number++;
  231.    return(1);
  232.    }
  233.  
  234. void Close_Targa_File (handle)
  235.    FILE_HANDLE *handle;
  236.    {
  237.    fclose (handle->file);
  238.    if (handle->buffer_size != 0)
  239.       free (handle->buffer);
  240.    }
  241.